﻿using System;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
using System.ComponentModel.Composition.Primitives;
using System.IO;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using NDBGen.Descriptors.Columns.Tokens;

namespace NDBGen.Tests
{
    [TestClass]
    public class CoverageTests
    {
        public CoverageTests()
        {
            this.Catalog = new DirectoryCatalog(new FileInfo(typeof(ColumnTests).Assembly.Location).DirectoryName);
            this.Container = new CompositionContainer(this.Catalog);
        }

        #region [ Helpers ]
        private ComposablePartCatalog Catalog { get; set; }
        private CompositionContainer Container { get; set; }
        
        private class TestData<TPluginContract, TTestContract>
        {
            [ImportMany]
            public Lazy<TTestContract, ITestMetadata>[] Tests { get; set; }

            [ImportMany]
            public TPluginContract[] Plugins { get; set; }
        }

        private void EnsureTestCoverage<TPluginContract, TTestContract>()
        {
            var data = new TestData<TPluginContract, TTestContract>();
            this.Container.SatisfyImportsOnce(data);

            foreach (var plugin in data.Plugins)
            {
                var pluginType = plugin.GetType();
                Assert.IsTrue(data.Tests.Any(t => t.Metadata.PluginTypes.Contains(pluginType)), "{0} is not covered by a {1}", pluginType, typeof(TTestContract));
            }
        }

        #endregion

        [TestMethod]
        public void EnsureParseTestCoverage()
        {
            EnsureTestCoverage<IColumnTokenDescriptor, ParseTest>();
        }
    }
}